`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/08/26 14:12:36
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module top(

    //ddr4接口
    output          C0_DDR4_act_n,
    output  [16:0]  C0_DDR4_adr,
    output  [1 :0]  C0_DDR4_ba,
    output  [0 :0]  C0_DDR4_bg,
    output  [0 :0]  C0_DDR4_ck_c,
    output  [0 :0]  C0_DDR4_ck_t,
    output  [0 :0]  C0_DDR4_cke,
    output  [0 :0]  C0_DDR4_cs_n,
    inout   [1 :0]  C0_DDR4_dm_n,
    inout   [15:0]  C0_DDR4_dq,
    inout   [1 :0]  C0_DDR4_dqs_c,
    inout   [1 :0]  C0_DDR4_dqs_t,
    output  [0 :0]  C0_DDR4_odt,
    output          C0_DDR4_reset_n,
    input           sysclk_p, 
    input           sysclk_n

);


    wire                        ddr_init_calib_complete         ; 

    wire                        wr_clk                          ; 
    wire                        wr_rstn                         ; 
    logic                        wr_req                          ; 
    logic    [31:0]              wr_addr                         ;      
    logic    [15:0]              wr_len                          ;
    logic    [127:0]             wr_data                         ;
    logic                        wr_valid                        ;
    wire                        wr_ready                        ;
    wire                        wr_busy                         ;
    wire                        wr_ddr_done                     ;
    wire    [1:0]               wr_status                       ;
    wire    [31:0]              WR_BASE_ADDR                    ;
    wire    [31:0]              WR_AXI_0_awaddr                 ;
    wire    [1:0]               WR_AXI_0_awburst                ;
    wire    [3:0]               WR_AXI_0_awcache                ;
    wire    [7:0]               WR_AXI_0_awlen                  ;
    wire    [0:0]               WR_AXI_0_awlock                 ;
    wire    [2:0]               WR_AXI_0_awprot                 ;
    wire    [3:0]               WR_AXI_0_awqos                  ;
    wire                        WR_AXI_0_awready                ;
    wire    [2:0]               WR_AXI_0_awsize                 ;
    wire                        WR_AXI_0_awvalid                ;
    wire                        WR_AXI_0_bready                 ;
    wire    [1:0]               WR_AXI_0_bresp                  ;
    wire                        WR_AXI_0_bvalid                 ;
    wire    [127:0]             WR_AXI_0_wdata                  ;
    wire                        WR_AXI_0_wlast                  ;
    wire                        WR_AXI_0_wready                 ;
    wire    [15:0]              WR_AXI_0_wstrb                  ;
    wire                        WR_AXI_0_wvalid                 ;
    wire    [15:0]              dbg_recived_data_num            ;
    wire    [15:0]              dbg_request_data_num            ;


    wire                        rd_clk                          ;
    wire                        rd_rst                          ;
    logic                        rd_req                          ;
    logic    [31:0]              rd_addr                         ;
    logic    [15:0]              rd_len                          ;
    wire                        rd_busy                         ;
    wire    [1:0]               rd_status                       ;
    wire    [127:0]             rd_data                         ;
    wire                        rd_valid                        ;
    logic                        rd_ready                        ;
    wire                        rd_last                         ;
    wire    [31:0]              RD_BASE_ADDR                    ;
    wire    [31:0]              RD_AXI_0_araddr                 ;
    wire    [1:0]               RD_AXI_0_arburst                ;
    wire    [3:0]               RD_AXI_0_arcache                ;
    wire    [7:0]               RD_AXI_0_arlen                  ;
    wire                        RD_AXI_0_arlock                 ;
    wire    [2:0]               RD_AXI_0_arprot                 ;
    wire    [3:0]               RD_AXI_0_arqos                  ;
    wire                        RD_AXI_0_arready                ;
    wire    [2:0]               RD_AXI_0_arsize                 ;
    wire                        RD_AXI_0_arvalid                ;
    wire    [127:0]             RD_AXI_0_rdata                  ;
    wire                        RD_AXI_0_rlast                  ;
    wire                        RD_AXI_0_rready                 ;
    wire    [1:0]               RD_AXI_0_rresp                  ;
    wire                        RD_AXI_0_rvalid                 ;



    //write/read test
    logic   tb_rst;
    logic [2:0] state;
    logic   tb_test_en;
    logic   tb_test_en_r1;
    logic   [31:0]tb_wr_addr;
    logic   [31:0]tb_rd_addr;
    logic   [15:0]tb_wr_len;
    logic   [15:0]tb_rd_len;
    logic   [15:0]cnt;
    always_ff @( posedge wr_clk ) begin
        if(tb_rst) begin
            wr_req <= 0;
            wr_addr <= 0;
            wr_len <= 0;
            rd_req <= 0;
            rd_addr <= 0;
            rd_len <= 0;
            tb_test_en_r1 <= 0;
            cnt <= 0;
            state <= 0;
        end
        else begin
            tb_test_en_r1 <= tb_test_en;
            case (state)
                0 : 
                begin
                    if(tb_test_en == 1 && tb_test_en_r1 == 0) begin
                        wr_req <= 1;
                        wr_addr <= tb_wr_addr;
                        wr_len <= tb_wr_len;
                        cnt <= 0;
                    end
                    else begin
                        wr_req <= 0;
                        state <= 0;
                    end 
                end 

                1 : 
                begin
                    wr_req <= 0;
                    wr_data <= cnt;
                    if(wr_valid == 1 && wr_ready == 1) begin
                         cnt <= cnt + 1;
                    end
                    if(cnt >= wr_len - 1) begin
                        wr_valid <= 0;
                        state <= 2;
                    end
                    else begin
                        wr_valid <= 1;
                        state <= 1;
                    end
                   
                end
                2 : 
                begin
                    if(wr_ddr_done == 1) begin
                        state <= 3;
                    end
                    else begin
                        state <= 2;
                    end
                end
                3 : 
                begin
                    rd_req <= 1;
                    rd_addr <= tb_rd_addr;
                    rd_len <= tb_rd_len;
                    state <= 4;
                end
                4 : begin
                    rd_req <= 0;
                    rd_ready <= 1;
                    if(rd_last == 1) begin
                        state <= 5;
                    end
                    else begin
                        state <= 4;
                    end
                end

                5 : 
                begin
                    state <= 0;
                end

                default: state <= 0;
            endcase
           

            
        end
    end

    //read test

    //check



    ddr4_writer#(
        .DDR4_DATA_WIDTH                    ( 16                            ),
        .DDR4_ADDR_WIDTH                    ( 32                            ),
        .USER_DATA_WIDTH                    ( 128                           ),
        .AXI_MM_BURST_LEN                   ( 64                            ),
        .DDR4_CAPASITY                      ( 32'h4000_0000                 )                
    )i_ddr4_writer(                                                     
        .wr_clk                             ( wr_clk                        ), 
        .wr_rst                             ( ~wr_rstn                      ), 
        .wr_req                             ( wr_req                        ), 
        .wr_addr                            ( wr_addr                       ),      
        .wr_len                             ( wr_len                        ),
        .wr_data                            ( wr_data                       ),
        .wr_valid                           ( wr_valid                      ),
        .wr_ready                           ( wr_ready                      ),
        .wr_busy                            ( wr_busy                       ),
        .wr_ddr_done                        ( wr_ddr_done                   ),
        .wr_status                          ( wr_status                     ),
        .WR_BASE_ADDR                       ( WR_BASE_ADDR                  ),
        .WR_AXI_0_awaddr                    ( WR_AXI_0_awaddr               ),
        .WR_AXI_0_awburst                   ( WR_AXI_0_awburst              ),
        .WR_AXI_0_awcache                   ( WR_AXI_0_awcache              ),
        .WR_AXI_0_awlen                     ( WR_AXI_0_awlen                ),
        .WR_AXI_0_awlock                    ( WR_AXI_0_awlock               ),
        .WR_AXI_0_awprot                    ( WR_AXI_0_awprot               ),
        .WR_AXI_0_awqos                     ( WR_AXI_0_awqos                ),
        .WR_AXI_0_awready                   ( WR_AXI_0_awready              ),
        .WR_AXI_0_awsize                    ( WR_AXI_0_awsize               ),
        .WR_AXI_0_awvalid                   ( WR_AXI_0_awvalid              ),
        .WR_AXI_0_bready                    ( WR_AXI_0_bready               ),
        .WR_AXI_0_bresp                     ( WR_AXI_0_bresp                ),
        .WR_AXI_0_bvalid                    ( WR_AXI_0_bvalid               ),
        .WR_AXI_0_wdata                     ( WR_AXI_0_wdata                ),
        .WR_AXI_0_wlast                     ( WR_AXI_0_wlast                ),
        .WR_AXI_0_wready                    ( WR_AXI_0_wready               ),
        .WR_AXI_0_wstrb                     ( WR_AXI_0_wstrb                ),
        .WR_AXI_0_wvalid                    ( WR_AXI_0_wvalid               ),
        .dbg_recived_data_num               ( dbg_recived_data_num          ),
        .dbg_request_data_num               ( dbg_request_data_num          )
    );


    ddr4_reader#(
        .DDR4_DATA_WIDTH                    (16                             ),
        .DDR4_ADDR_WIDTH                    (32                             ),
        .USER_DATA_WIDTH                    (128                            ),
        .AXI_MM_BURST_LEN                   (64                             ),
        .DDR4_CAPASITY                      (32'h4000_0000                  ) 
    )i_ddr4_reader(
        .rd_clk                             ( rd_clk                        ),
        .rd_rst                             ( rd_rst                        ),
        .rd_req                             ( rd_req                        ),
        .rd_addr                            ( rd_addr                       ),
        .rd_len                             ( rd_len                        ),
        .rd_busy                            ( rd_busy                       ),
        .rd_status                          ( rd_status                     ),
        .rd_data                            ( rd_data                       ),
        .rd_valid                           ( rd_valid                      ),
        .rd_ready                           ( rd_ready                      ),
        .rd_last                            ( rd_last                       ),
        .RD_BASE_ADDR                       ( RD_BASE_ADDR                  ),
        .RD_AXI_0_araddr                    ( RD_AXI_0_araddr               ),
        .RD_AXI_0_arburst                   ( RD_AXI_0_arburst              ),
        .RD_AXI_0_arcache                   ( RD_AXI_0_arcache              ),
        .RD_AXI_0_arlen                     ( RD_AXI_0_arlen                ),
        .RD_AXI_0_arlock                    ( RD_AXI_0_arlock               ),
        .RD_AXI_0_arprot                    ( RD_AXI_0_arprot               ),
        .RD_AXI_0_arqos                     ( RD_AXI_0_arqos                ),
        .RD_AXI_0_arready                   ( RD_AXI_0_arready              ),
        .RD_AXI_0_arsize                    ( RD_AXI_0_arsize               ),
        .RD_AXI_0_arvalid                   ( RD_AXI_0_arvalid              ),
        .RD_AXI_0_rdata                     ( RD_AXI_0_rdata                ),
        .RD_AXI_0_rlast                     ( RD_AXI_0_rlast                ),
        .RD_AXI_0_rready                    ( RD_AXI_0_rready               ),
        .RD_AXI_0_rresp                     ( RD_AXI_0_rresp                ),
        .RD_AXI_0_rvalid                    ( RD_AXI_0_rvalid               )
    );





    //ddr4 单读写通道
    ddr4_wrapper ddr4_single(
        .HYM_RD_AXI_ACLK                    ( rd_clk                        ),
        .HYM_RD_AXI_ARESETN                 ( rd_rstn                       ),
        .HYM_RD_SLAVE_BASE_ADDR             ( RD_BASE_ADDR                  ),
        .HYM_WR_AXI_ACLK                    ( wr_clk                        ),
        .HYM_WR_AXI_ARESETN                 ( wr_rstn                       ),
        .HYM_WR_SLAVE_BASE_ADDR             ( WR_BASE_ADDR                  ),
        .RD_HYM_AXI_araddr                  ( RD_AXI_0_araddr               ),
        .RD_HYM_AXI_arburst                 ( RD_AXI_0_arburst              ),
        .RD_HYM_AXI_arcache                 ( RD_AXI_0_arcache              ),
        .RD_HYM_AXI_arlen                   ( RD_AXI_0_arlen                ),
        .RD_HYM_AXI_arlock                  ( RD_AXI_0_arlock               ),
        .RD_HYM_AXI_arprot                  ( RD_AXI_0_arprot               ),
        .RD_HYM_AXI_arqos                   ( RD_AXI_0_arqos                ),
        .RD_HYM_AXI_arready                 ( RD_AXI_0_arready              ),
        .RD_HYM_AXI_arsize                  ( RD_AXI_0_arsize               ),
        .RD_HYM_AXI_arvalid                 ( RD_AXI_0_arvalid              ),
        .RD_HYM_AXI_rdata                   ( RD_AXI_0_rdata                ),
        .RD_HYM_AXI_rlast                   ( RD_AXI_0_rlast                ),
        .RD_HYM_AXI_rready                  ( RD_AXI_0_rready               ),
        .RD_HYM_AXI_rresp                   ( RD_AXI_0_rresp                ),
        .RD_HYM_AXI_rvalid                  ( RD_AXI_0_rvalid               ),
        .WR_HYM_AXI_awaddr                  ( WR_AXI_0_awaddr               ),
        .WR_HYM_AXI_awburst                 ( WR_AXI_0_awburst              ),
        .WR_HYM_AXI_awcache                 ( WR_AXI_0_awcache              ),
        .WR_HYM_AXI_awlen                   ( WR_AXI_0_awlen                ),
        .WR_HYM_AXI_awlock                  ( WR_AXI_0_awlock               ),
        .WR_HYM_AXI_awprot                  ( WR_AXI_0_awprot               ),
        .WR_HYM_AXI_awqos                   ( WR_AXI_0_awqos                ),
        .WR_HYM_AXI_awready                 ( WR_AXI_0_awready              ),
        .WR_HYM_AXI_awsize                  ( WR_AXI_0_awsize               ),
        .WR_HYM_AXI_awvalid                 ( WR_AXI_0_awvalid              ),
        .WR_HYM_AXI_bready                  ( WR_AXI_0_bready               ),
        .WR_HYM_AXI_bresp                   ( WR_AXI_0_bresp                ),
        .WR_HYM_AXI_bvalid                  ( WR_AXI_0_bvalid               ),
        .WR_HYM_AXI_wdata                   ( WR_AXI_0_wdata                ),
        .WR_HYM_AXI_wlast                   ( WR_AXI_0_wlast                ),
        .WR_HYM_AXI_wready                  ( WR_AXI_0_wready               ),
        .WR_HYM_AXI_wstrb                   ( WR_AXI_0_wstrb                ),
        .WR_HYM_AXI_wvalid                  ( WR_AXI_0_wvalid               ),

        .c0_init_calib_complete_0           ( ddr_init_calib_complete       ),
        .ddr4_rtl_0_act_n                   ( C0_DDR4_act_n                 ),
        .ddr4_rtl_0_adr                     ( C0_DDR4_adr                   ),
        .ddr4_rtl_0_ba                      ( C0_DDR4_ba                    ),
        .ddr4_rtl_0_bg                      ( C0_DDR4_bg                    ),
        .ddr4_rtl_0_ck_c                    ( C0_DDR4_ck_c                  ),
        .ddr4_rtl_0_ck_t                    ( C0_DDR4_ck_t                  ),
        .ddr4_rtl_0_cke                     ( C0_DDR4_cke                   ),
        .ddr4_rtl_0_cs_n                    ( C0_DDR4_cs_n                  ),
        .ddr4_rtl_0_dm_n                    ( C0_DDR4_dm_n                  ),
        .ddr4_rtl_0_dq                      ( C0_DDR4_dq                    ),
        .ddr4_rtl_0_dqs_c                   ( C0_DDR4_dqs_c                 ),
        .ddr4_rtl_0_dqs_t                   ( C0_DDR4_dqs_t                 ),
        .ddr4_rtl_0_odt                     ( C0_DDR4_odt                   ),
        .ddr4_rtl_0_reset_n                 ( C0_DDR4_reset_n               ),
        .diff_clock_rtl_0_clk_n             ( sysclk_n                      ),
        .diff_clock_rtl_0_clk_p             ( sysclk_p                      )
    );
endmodule
